<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  <div class="fangdou">
    111
  </div>
  <script>
    // 1.防抖节流 手写
    // function event() {
    //   console.log('111');
    // }

    // let dom = document.querySelector(".fangdou")
    // dom.onclick = fangdou(event, 1000, false)

    // function fangdou(fn,wait,imm){
    //   let timeout
    //   return function(){
    //     if(timeout) clearTimeout(timeout)
    //     if(imm){
    //       // 立即执行
    //       if(!timeout) fn.apply(this,arguments)
    //       timeout = setTimeout(function(){
    //         timeout = null
    //       },wait)
    //     }else{
    //       // 非立即执行
    //       timeout = setTimeout(function(){
    //         fn.apply(this,arguments)
    //       },wait)
    //     }
    //   }
    // }

    // function jieliu(fn, wait, imm) {
    //   let timeout
    //   return function () {
    //     if (!timeout) {
    //       if (imm) {
    //         // 立即执行
    //         fn.apply(this, arguments)
    //         timeout = setTimeout(function () {
    //           timeout = null
    //         }, wait)
    //       } else {
    //         // 非立即执行
    //         timeout = setTimeout(function () {
    //           timeout = null
    //           fn.apply(this, arguments)
    //         }, wait)
    //       }
    //     }
    //   }
    // }



    // 2. 深拷贝
    // function deepClone(obj, hash = new WeakMap()) {
    //   /* 1.对传入的参数值进行判断 */

    //   // 当传入的参数是null或者undefined时 利用null==undefined 直接返回
    //   if (obj == null) return obj;

    //   // 当传入的是日期格式的对象时 再将其拷贝一层
    //   if (obj instanceof Date) return new Date(obj);

    //   // 当传入的是正则表达式格式的对象时 再将其拷贝一层
    //   if (obj instanceof RegExp) return new RegExp(obj);

    //   // 当初入的是函数对象时 直接返回
    //   if (typeof obj !== "object") return obj;

    //   // 如果拷贝的对象是存在,直接从weakmap中返回即可
    //   if (hash.has(obj)) return hash.get(obj);

    //   // 数组以及对象的拷贝
    //   let cloneObj = new obj.constructor();

    //   hash.set(obj, cloneObj);
    //   for (const key in obj) {
    //     // for...in循环会遍历obj原型上的属性
    //     // 通过obj.hasOwnProperty只遍历obj对象上的属性
    //     if (obj.hasOwnProperty(key)) {
    //       // 递归拷贝每一项的值
    //       cloneObj[key] = deepClone(obj[key], hash);
    //     }
    //   }
    //   return cloneObj;
    // }


    // function cloneDeep(obj, map = new WeakMap()) {
    //   if (obj == null) return obj
    //   if (toString.call(obj) == '[object RegExp]') return new RegExp()
    //   if (toString.call(obj) == '[object Date]') return new Date()
    //   if (typeof obj != 'object') return obj
    //   if (map.has(obj)) {
    //     return map.get(obj)
    //   }
    //   let cloneObj = new obj.constructor()
    //   map.set(obj, cloneObj)
    //   for (let key in obj) {
    //     if (obj.hasOwnProperty(key)) {
    //       cloneObj[key] = cloneDeep(obj[key], map)
    //     }
    //   }
    //   return cloneObj
    // }
    // const obj = { age: { name: "小林", age1: { name: "小林" } } };
    // const n = cloneDeep(obj);
    // n.age.name = "小n";
    // console.log(obj);
    // console.log(n);


    // 3. 手写promise
    // 三个状态：PENDING、FULFILLED、REJECTED
    // const PENDING = 'PENDING';
    // const FULFILLED = 'FULFILLED';
    // const REJECTED = 'REJECTED';

    // class Promise {
    //   constructor(executor) {
    //     // 默认状态为 PENDING
    //     this.status = PENDING;
    //     // 存放成功状态的值，默认为 undefined
    //     this.value = undefined;
    //     // 存放失败状态的值，默认为 undefined
    //     this.reason = undefined;

    //     // 调用此方法就是成功
    //     let resolve = (value) => {
    //       // 状态为 PENDING 时才可以更新状态，防止 executor 中调用了两次 resovle/reject 方法
    //       if (this.status === PENDING) {
    //         this.status = FULFILLED;
    //         this.value = value;
    //       }
    //     }

    //     // 调用此方法就是失败
    //     let reject = (reason) => {
    //       // 状态为 PENDING 时才可以更新状态，防止 executor 中调用了两次 resovle/reject 方法
    //       if (this.status === PENDING) {
    //         this.status = REJECTED;
    //         this.reason = reason;
    //       }
    //     } 

    //     try {
    //       // 立即执行，将 resolve 和 reject 函数传给使用者  
    //       executor(resolve, reject)
    //     } catch (error) {
    //       // 发生异常时执行失败逻辑
    //       reject(error)
    //     }
    //   }

    //   // 包含一个 then 方法，并接收两个参数 onFulfilled、onRejected
    //   then(onFulfilled, onRejected) {
    //     if (this.status === FULFILLED) {
    //       onFulfilled(this.value)
    //     }

    //     if (this.status === REJECTED) {
    //       onRejected(this.reason)
    //     }
    //   }
    // }

    // const promise = new Promise((resolve, reject) => {
    //   resolve('成功');
    // }).then(
    //   (data) => {
    //     console.log('success', data)
    //   },
    //   (err) => {
    //     console.log('faild', err)
    //   }
    // )







  </script>
</body>

</html>